#include <QMessageBox>
#include <QFileDialog>
#include "MainWindow.hpp"
#include "DialogImport.hpp"
#include "DialogNewMap.hpp"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent):
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initMenus();
    initWidgets();
    initResources();

    Tab*    newTab = new Tab(new Map(20, 20));
    _tabs.push_back(newTab);

    ui->tabWidget->insertTab(0, newTab, QIcon("./Datas/icon_map.png"), "New map");
    ui->tabWidget->currentWidget();
}

MainWindow::~MainWindow()
{
    delete ui;
}


void    MainWindow::initMenus()
{
    QObject::connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(menuActionAbout()));

    QObject::connect(ui->actionNewMap, SIGNAL(triggered()), this, SLOT(menuActionNewMap()));
    QObject::connect(ui->actionLoadMap, SIGNAL(triggered()), this, SLOT(menuActionLoadMap()));
    QObject::connect(ui->actionSaveMap, SIGNAL(triggered()), this, SLOT(menuActionSaveMap()));
    QObject::connect(ui->actionSaveMapAs, SIGNAL(triggered()), this, SLOT(menuActionSaveMapAs()));
    QObject::connect(ui->actionImport, SIGNAL(triggered()), this, SLOT(menuActionImport()));
    QObject::connect(ui->actionQuit, SIGNAL(triggered()), qApp, SLOT(quit()));

    QObject::connect(ui->treeWidgetTileSheets, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(handleTreeWidgetClick(QTreeWidgetItem*, int)));

    QObject::connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(handleCloseTab(int)));

    ui->actionNewMap->setShortcut(QKeySequence("Ctrl+N"));
    ui->actionLoadMap->setShortcut(QKeySequence("Ctrl+L"));
    ui->actionSaveMap->setShortcut(QKeySequence("Ctrl+S"));
    ui->actionSaveMapAs->setShortcut(QKeySequence("Ctrl+Shift+S"));
    ui->actionImport->setShortcut(QKeySequence("Ctrl+I"));
    ui->actionQuit->setShortcut(QKeySequence("Ctrl+Q"));
    ui->actionAbout->setShortcut(QKeySequence("F1"));
}

void    MainWindow::initWidgets()
{
    this->centralWidget()->setLayout(ui->mainLayout);
}

void    MainWindow::initResources()
{
    TileCutter  cutter(_treeViewPopulation);

    cutter.cutSprite("Blank", "./Datas/blank.jpg", 64, 64);
    cutter.cutSprite("Bricks brown", "./Datas/brick_brown.jpg", 64, 64);
    cutter.cutSprite("Bricks red", "./Datas/brick_red.jpg", 128, 128);
    cutter.cutSprite("Floor indoor 1", "./Datas/floor_indor1.jpg", 64, 64);
    cutter.cutSprite("Floor indoor 2", "./Datas/floor_indor2.jpg", 128, 128);
    cutter.cutSprite("Glass block blue", "./Datas/glass_block_blue.jpg", 64, 64);
    cutter.cutSprite("Grass 1", "./Datas/grass1.jpg", 128, 128);
    cutter.cutSprite("Grass 2", "./Datas/grass2.jpg", 128, 128);
    cutter.cutSprite("Parquet", "./Datas/parquet.jpg", 256, 256);
    cutter.cutSprite("Rock", "./Datas/rock.jpg", 64, 64);
    cutter.cutSprite("Sand", "./Datas/sand.jpg", 128, 128);
    cutter.cutSprite("Snow", "./Datas/snow.jpg", 256, 256);

    populateTreeView();
}

//
// Handle actions
//
void    MainWindow::handleCloseTab(int index)
{
    Tab*        toClose = dynamic_cast<Tab*>(ui->tabWidget->widget(index));
    Map&        map = toClose->getMap();

    if (QMessageBox::question(this, "Save map", "Do you want to save the current map ?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
    {
        if (map.getPath() == "")
        {
            QString	path = QFileDialog::getSaveFileName(this, QString("Save map..."), QString("."), QString("XML file (*.xml)"));

            if (path != "")
            {
                QStringList     cuttedPath = path.split('/');
                QString         name = cuttedPath.last();

                map.setPath(path);
                map.setName(name);
                _mapManager.save(_treeViewPopulation, map, path);
            }
        }
        else
        {
            _mapManager.save(_treeViewPopulation, map, map.getPath());
        }
    }
    ui->tabWidget->removeTab(index);
}

void    MainWindow::handleTreeWidgetClick(QTreeWidgetItem *item, int column)
{
    if (item->child(0) == 0)
    {
        QString     itemName = item->text(0);
        QPixmap*    selectedImage = NULL;

        std::list<SpriteSheet*>::iterator         mainListBegin = _treeViewPopulation.begin();
        const std::list<SpriteSheet*>::iterator   mainListEnd = _treeViewPopulation.end();

        while (mainListBegin != mainListEnd)
        {
            selectedImage = (*mainListBegin)->getImageFromName(itemName);
            if (selectedImage != NULL)
                break;
            ++mainListBegin;
        }

        if (selectedImage != NULL)
        {
            int     itW = 0, nbWidget = ui->tabWidget->count();
            Tab*    tab;

            while (itW < nbWidget)
            {
                tab = dynamic_cast<Tab*>(ui->tabWidget->widget(itW));
                tab->setSelectedTile(itemName, selectedImage);
                itW++;
            }
        }
    }
}

//
// Handle menus actions
//
void    MainWindow::menuActionAbout()
{
    QMessageBox::information(this, tr("About"),
                             tr("2D game map editor\nMade by Yann Viens (student ID : 11129068) and Dmitri Nukilin (Student ID : 12980020)"));
}

void    MainWindow::menuActionNewMap()
{
    DialogNewMap    newMapDialog;

    newMapDialog.exec();
    if (newMapDialog.canCreateNewMap())
    {
        int     mapWidth = newMapDialog.getMapWidth();
        int     mapHeight = newMapDialog.getMapHeight();

        Map*    newMap = new Map(mapWidth, mapHeight);
        Tab*    newTab = new Tab(newMap);

        ui->tabWidget->addTab(newTab, QIcon("./Datas/icon_map.png"), "New map");
        ui->tabWidget->setCurrentWidget(newTab);
    }
}

void    MainWindow::menuActionImport()
{
    DialogImport    importDialog(_treeViewPopulation, this);

    importDialog.exec();

    if (importDialog.spritesLoaded())
        populateTreeView();
}

void    MainWindow::menuActionLoadMap()
{
    QString	filePath = QFileDialog::getOpenFileName(this, QString("Load map..."), QString("."), QString("XML file (*.xml)"));

    if (filePath != "")
    {
        Map*    newMap = _mapManager.load(filePath, _treeViewPopulation);

        Tab*    newTab = new Tab(newMap);

        ui->tabWidget->addTab(newTab, QIcon("./Datas/icon_map.png"), newMap->getName());
        ui->tabWidget->setCurrentWidget(newTab);
        populateTreeView();
    }
}

void    MainWindow::populateTreeView()
{
    std::list<SpriteSheet*>::iterator      listBegin = _treeViewPopulation.begin();
    std::list<SpriteSheet*>::iterator      listEnd = _treeViewPopulation.end();

    ui->treeWidgetTileSheets->clear();

    while (listBegin != listEnd)
    {
        QTreeWidgetItem*    rootItem = new QTreeWidgetItem(ui->treeWidgetTileSheets);

        rootItem->setText(0, (*listBegin)->getName());

        std::list<std::pair<QString, QPixmap> >*    sprites = (*listBegin)->getSprites();

        std::list<std::pair<QString, QPixmap> >::iterator     itBegin = sprites->begin();
        std::list<std::pair<QString, QPixmap> >::iterator     itEnd = sprites->end();

        while (itBegin != itEnd)
        {
            QTreeWidgetItem*     listItem = new QTreeWidgetItem(rootItem);
            listItem->setText(0, (*itBegin).first);
            listItem->setIcon(0, QIcon((*itBegin).second));

            ++itBegin;
        }
        ++listBegin;
    }
}

void    MainWindow::menuActionSaveMap()
{
    Tab*            currentTab = dynamic_cast<Tab*>(ui->tabWidget->currentWidget());
    Map&            currentMap = currentTab->getMap();
    QString const&  path = currentMap.getPath();

    if (path != "")
    {
        _mapManager.save(_treeViewPopulation, currentMap, path);
    }
    else
        menuActionSaveMapAs();
}


void    MainWindow::menuActionSaveMapAs()
{
    QString	path = QFileDialog::getSaveFileName(this, QString("Save map..."), QString("."), QString("XML file (*.xml)"));

    if (path != "")
    {
        Tab*    currentTab = dynamic_cast<Tab*>(ui->tabWidget->currentWidget());
        Map&    currentMap = currentTab->getMap();

        QStringList     cuttedPath = path.split('/');
        QString         name = cuttedPath.last();

        currentMap.setName(name);
        currentMap.setPath(path);
        _mapManager.save(_treeViewPopulation, currentMap, path);

        ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), name);
    }
}

